package cn.yujiago.miaosha.controller;

import cn.yujiago.miaosha.access.AccessLimit;
import cn.yujiago.miaosha.component.UserContext;
import cn.yujiago.miaosha.constant.UserConstant;
import cn.yujiago.miaosha.dto.CodeMsg;
import cn.yujiago.miaosha.dto.GoodsDTO;
import cn.yujiago.miaosha.dto.Result;
import cn.yujiago.miaosha.entity.Goods;
import cn.yujiago.miaosha.entity.MiaoshaOrder;
import cn.yujiago.miaosha.exception.MiaoshaException;
import cn.yujiago.miaosha.rabbitmq.MQSender;
import cn.yujiago.miaosha.rabbitmq.MiaoshaMessage;
import cn.yujiago.miaosha.redis.GoodsKey;
import cn.yujiago.miaosha.redis.MiaoshaKey;
import cn.yujiago.miaosha.redis.RedisService;
import cn.yujiago.miaosha.service.GoodsService;
import cn.yujiago.miaosha.service.MiaoshaService;
import cn.yujiago.miaosha.service.OrderService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.List;

@RestController
@RequestMapping("/miaosha")
public class MiaoshaController implements InitializingBean {

    @Autowired
    private MiaoshaService miaoshaService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private MQSender sender;

    @Override
    public void afterPropertiesSet() throws Exception {
        // 系统初始化时，将库存存放到缓存中，便于下订单时预减库存
        List<GoodsDTO> goodsList = goodsService.getMiaoshaList();
        if(goodsList == null) {
            return;
        }
        for(GoodsDTO goods : goodsList) {
            redisService.set(GoodsKey.getMiaoshaGoodsStock, ""+goods.getId(), goods.getStockCount());
        }
    }

    @GetMapping("/list")
    public Result<List<GoodsDTO>> list(){
        return miaoshaService.getMiaoshaList();
    }

    @GetMapping("/verifyCode")
    public Result<String> getMiaoshaVerifyCode(HttpServletResponse response, @RequestParam("goodsId")long goodsId) {
        BufferedImage image = miaoshaService.createVerifyCode(UserContext.getUser(), goodsId);
        try (
                OutputStream out = response.getOutputStream()
        ){
            ImageIO.write(image, "JPEG", out);
            return Result.success(null);
        }catch(Exception e) {
            e.printStackTrace();
            return Result.error(CodeMsg.MIAOSHA_FAIL);
        }
    }

    @AccessLimit(seconds=30, maxCount=10, needLogin=true)
    @GetMapping("/path")
    public Result<String> getMiaoshaPath(@RequestParam("goodsId") Long goodsId, @RequestParam(value="verifyCode") String verifyCode) {
        // 验证码
        boolean check = miaoshaService.checkVerifyCode(UserContext.getUser(), goodsId, verifyCode);
        if(!check) {
            throw new MiaoshaException(CodeMsg.CODE_REEOE);
        }
        // 生成随机秒杀path
        String path = miaoshaService.createMiaoshaPath(UserContext.getUser().getId(), goodsId);
        return Result.success(path);
    }

    @PostMapping("/{path}/do_miaosha")
    public Result doMiaosha(@RequestParam("goodsId") Long goodsId, @PathVariable("path") String path, @RequestParam("verifyCode") Long verifyCode) {

        //验证随机生成的path
        boolean checkPath = miaoshaService.checkPath(UserContext.getUser().getId(), goodsId, path);
        if(!checkPath){
            throw new MiaoshaException(CodeMsg.REQUEST_ILLEGAL);
        }

        //判断是否已经秒杀到了，一人只能秒杀一件同类商品
        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(UserContext.getUser().getId(), goodsId);
        if(order != null) {
            throw new MiaoshaException(CodeMsg.REPEATE_MIAOSHA);
        }

        //预减库存
        long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock, ""+goodsId);
        if(stock < 0) {
            throw new MiaoshaException(CodeMsg.MIAO_SHA_OVER);
        }

        //入队
        MiaoshaMessage mm = new MiaoshaMessage();
        mm.setUserId(UserContext.getUser().getId());
        mm.setGoodsId(goodsId);
        sender.sendMiaoshaMessage(mm);
        return Result.success(0);//排队中
    }

    /**
     * orderId：成功
     * -1：秒杀失败
     * 0： 排队中
     * */
    @GetMapping("/result")
    public Result<Long> miaoshaResult(@RequestParam("goodsId") Long goodsId) {
        Long result = miaoshaService.getMiaoshaResult(UserContext.getUser().getId(), goodsId);
        return Result.success(result);
    }
}
